package io.adrainty.bolee.security.repository.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.adrainty.bolee.framework.commons.utils.IdentifierNoUtil;
import io.adrainty.bolee.security.mapper.IDeptMapper;
import io.adrainty.bolee.security.mapper.IDeptPostUserMapper;
import io.adrainty.bolee.security.models.bo.DeptBO;
import io.adrainty.bolee.security.models.bo.DeptPostUserBO;
import io.adrainty.bolee.security.models.entity.DeptEntity;
import io.adrainty.bolee.security.repository.IDeptRepository;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Set;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/3 上午1:04
 */

@Repository
public class DeptRepositoryImpl implements IDeptRepository {

    @Resource
    private IDeptMapper deptMapper;

    @Resource
    private IDeptPostUserMapper deptPostUserMapper;

    @Override
    public boolean saveBatchDeptPostUser(List<DeptPostUserBO> deptPostUserList) {
        deptPostUserMapper.insert(deptPostUserList);
        return deptPostUserList.stream().noneMatch(bo -> bo.getId() == null);
    }

    @Override
    public void deleteUserDeptByUserId(Long userId) {
        Wrapper<DeptPostUserBO> wrapper = Wrappers.lambdaQuery(DeptPostUserBO.class)
                .eq(DeptPostUserBO::getUserId, userId);
        deptPostUserMapper.delete(wrapper);
    }

    @Override
    public List<DeptPostUserBO> findDeptPostUserListByDeptNo(String deptNo) {
        Wrapper<DeptPostUserBO> wrapper = Wrappers.lambdaQuery(DeptPostUserBO.class)
                .eq(DeptPostUserBO::getDeptNo, deptNo);
        return deptPostUserMapper.selectList(wrapper);
    }

    @Override
    public List<DeptPostUserBO> findDeptPostUserListByUserId(List<Long> userIdList) {
        Wrapper<DeptPostUserBO> wrapper = Wrappers.lambdaQuery(DeptPostUserBO.class)
                .in(DeptPostUserBO::getUserId, userIdList);
        return deptPostUserMapper.selectList(wrapper);
    }

    @Override
    public List<DeptEntity> findSubDeptList(String parentDeptNo) {
        if (StringUtils.isBlank(parentDeptNo)) return List.of();
        Wrapper<DeptBO> wrapper = Wrappers.lambdaQuery(DeptBO.class)
                .likeRight(DeptBO::getParentDeptNo, IdentifierNoUtil.processNo(parentDeptNo))
                .orderByAsc(DeptBO::getSortNo);
        List<DeptBO> deptBOList = deptMapper.selectList(wrapper);
        return BeanUtil.copyToList(deptBOList, DeptEntity.class);
    }

    @Override
    public List<DeptEntity> findSubLevel1DeptList(String companyNo, String parentDeptNo) {
        if (StringUtils.isBlank(parentDeptNo)) return List.of();
        Wrapper<DeptBO> wrapper = Wrappers.lambdaQuery(DeptBO.class)
                .eq(DeptBO::getParentDeptNo, parentDeptNo)
                .eq(DeptBO::getCompanyNo, companyNo);
        List<DeptBO> deptBOList = deptMapper.selectList(wrapper);
        return BeanUtil.copyToList(deptBOList, DeptEntity.class);
    }

    @Override
    public boolean save(DeptEntity deptEntity) {
        DeptBO deptBO = BeanUtil.copyProperties(deptEntity, DeptBO.class);
        boolean result = deptMapper.insert(deptBO) > 0;
        if (result) BeanUtil.copyProperties(deptBO, deptEntity);
        return result;
    }

    @Override
    public List<DeptEntity> findDeptByRoleIds(List<Long> roleIdList) {
        return deptMapper.findDeptByRoleIds(roleIdList);
    }

    @Override
    public List<DeptEntity> findDeptList(DeptEntity entity) {
        Wrapper<DeptBO> wrapper = getWrapper(entity);
        List<DeptBO> deptBOList = deptMapper.selectList(wrapper);
        return BeanUtil.copyToList(deptBOList, DeptEntity.class);
    }

    @Override
    public IPage<DeptEntity> pageDept(Integer pageNum, Integer pageSize, DeptEntity deptEntity) {
        Page<DeptBO> page = new Page<>(pageNum, pageSize);
        Wrapper<DeptBO> wrapper = getWrapper(deptEntity);
        return deptMapper.selectPage(page, wrapper).convert(item -> BeanUtil.copyProperties(item, DeptEntity.class));
    }

    @Override
    public boolean updateDept(DeptEntity entity) {
        DeptBO deptBO = BeanUtil.toBean(entity, DeptBO.class);
        return deptMapper.updateById(deptBO) > 0;
    }

    @Override
    public List<DeptEntity> findDeptByNoList(Set<String> deptNoList) {
        Wrapper<DeptBO> wrapper = Wrappers.lambdaQuery(DeptBO.class)
                .in(DeptBO::getDeptNo, deptNoList)
                .orderByAsc(DeptBO::getSortNo)
                .orderByDesc(DeptBO::getCreatedTime);
        List<DeptBO> deptBOList = deptMapper.selectList(wrapper);
        return BeanUtil.copyToList(deptBOList, DeptEntity.class);
    }

    private Wrapper<DeptBO> getWrapper(DeptEntity entity) {
        return Wrappers.lambdaQuery(DeptBO.class)
                .eq(StringUtils.isNotBlank(entity.getCompanyNo()), DeptBO::getCompanyNo, entity.getCompanyNo())
                .eq(StringUtils.isNotBlank(entity.getParentDeptNo()), DeptBO::getParentDeptNo, entity.getParentDeptNo())
                .eq(StringUtils.isNotBlank(entity.getDeptNo()), DeptBO::getDeptNo, entity.getDeptNo())
                .likeRight(StringUtils.isNotBlank(entity.getDeptName()), DeptBO::getDeptName, entity.getDeptName())
                .eq(entity.getDataState() != null, DeptBO::getDataState, entity.getDataState())
                .orderByAsc(DeptBO::getSortNo);
    }


}
